﻿using System;
using Xenta.Utils;

namespace Xenta.Structs
{
    /// <summary>
    /// Represents the numeric format structure.
    /// </summary>
    /// <remarks>
    /// </remarks>
    public struct NumericFormat
    {
        #region Constants

        /// <summary>
        /// Represents the delimiter string which is 
        /// being used to separate parts of the format.
        /// </summary>
        public const string FMT_PARTS_DELIMITER = "|";

        #endregion

        #region Properties

        /// <summary>
        /// Gets or sets the decimal separator.
        /// </summary>
        public string DecimalSeparator;

        /// <summary>
        /// Gets or sets the group separator.
        /// </summary>
        public string GroupSeparator;

        /// <summary>
        /// Gets or sets the format string.
        /// </summary>
        public string Format;

        /// <summary>
        /// Gets or sets the pattern string.
        /// </summary>
        public string Pattern;

        #endregion

        #region Methods

        /// <summary>
        /// Uses current numeric format to conver decimal 
        /// value to its string representation.
        /// </summary>
        /// <param name="value">The decimal value.</param>
        /// <returns>The string representation.</returns>
        public string Convert(decimal value)
        {
            return NumericHelper.ToString(value, DecimalSeparator, GroupSeparator, Format);
        }

        /// <summary>
        /// Uses current numeric format to conver decimal string 
        /// representation into a decimal value.
        /// </summary>
        /// <param name="value">The decimal string representation.</param>
        /// <returns>The decimal value.</returns>
        public decimal Convert(string value)
        {
            return NumericHelper.Parse(value, DecimalSeparator, GroupSeparator, Pattern);
        }

        /// <summary>
        /// Gets the string representation of the format.
        /// </summary>
        /// <returns>The string representation of the format.</returns>
        public override string ToString()
        {
            return String.Format("{1}{0}{2}{0}{3}{0}{4}",
                FMT_PARTS_DELIMITER, 
                DecimalSeparator, 
                GroupSeparator, 
                Format, 
                Pattern);
        }

        #endregion

        #region Static

        #region Properties

        /// <summary>
        /// Gets the default format structure.
        /// </summary>
        public static NumericFormat Default
        {
            get
            {
                return new NumericFormat
                {
                    DecimalSeparator = ".",
                    GroupSeparator = ",",
                    Format = "#,##0.00##",
                    Pattern = @"(\,{0,1}\d{1,3})+(\.\d{0,4}){0,1}"
                };
            }
        }

        #endregion

        #region Methods

        /// <summary>
        /// Gets the format structure from its string representation.
        /// </summary>
        /// <param name="s">The string representation of the format.</param>
        /// <returns>The format structure.</returns>
        public static NumericFormat Parse(string s)
        {
            if(String.IsNullOrWhiteSpace(s))
                return Default;

            var parts = s.Split(new []
            {
                FMT_PARTS_DELIMITER
            }, StringSplitOptions.None);
            if(parts.Length != 4)
                return Default;

            return  new NumericFormat
            {
                DecimalSeparator = parts[0],
                GroupSeparator = parts[1],
                Format = parts[2],
                Pattern = parts[3]
            };
        }

        #endregion

        #endregion
    }
}
